#include "stringverifytest.h"
#include "common/logger/logger.h"
#include "common/stringverify/stringverify.h"

#ifdef Q_OS_WIN
#include <windows.h>
#endif

StringVerifyTest::StringVerifyTest(QObject* parent)
{
}
StringVerifyTest::~StringVerifyTest()
{
}
void StringVerifyTest::initTestCase()
{
}
void StringVerifyTest::tstStringVerify()
{
	LOG_INFO("======================= 邮箱测试 =======================");
	// ✅ 合法邮箱
	std::vector<std::string> validEmails = {
			"test@example.com",
			"user.name@domain.co",
			"user_name+tag@example.co.uk",
			"user-name@sub.domain.com"};
	for (const auto& e: validEmails)
		LOG_INFO("✅ Email test: " + e + " -> ", StringVerify::isEmailAddr(e));

	// ❌ 非法邮箱
	std::vector<std::string> invalidEmails = {
			"invalid-email",
			"a@b.c",
			"plainaddress",
			"@missinguser.com",
			"",
			"unicode邮件@例子.中国"};
	for (const auto& e: invalidEmails)
		LOG_INFO("❌ Email test: " + e + " -> ", StringVerify::isEmailAddr(e));

	LOG_INFO("======================= 手机号测试 =======================");
	// ✅ 合法手机号
	std::vector<std::string> validPhones = {
			"13812345678",
			"19912345678",
			"+8613812345678",
			"1234567",
			"99999999999",
			"00000000000",
			"0044123456789",
			"010-12345678"};
	for (const auto& p: validPhones)
		LOG_INFO("✅ Phone test: " + p + " -> ", StringVerify::isPhoneNumber(p));

	// ❌ 非法手机号
	// 分类：空 / 空白
	std::vector<std::string> invalidPhones_empty = {
			"",   // 空字符串
			" ",  // 空格
			"\t", // 制表符
			"\r\n"// 换行
	};

	// 分类：长度太短（少于7位有效数字）
	std::vector<std::string> invalidPhones_tooShort = {
			"123",   // 太短
			"123456",// 6 位
			"+1",    // + 后没有足够数字
			"00",    // 仅 00
	};

	// 分类：长度过长（去掉非数字后超过15位 E.164 限制）
	std::vector<std::string> invalidPhones_tooLong = {
			"+1234567890123456",  // 16 位数字（超出 E.164）
			"001234567890123456", // 00 开头后超长
			"12345678901234567890"// 过长纯数字
	};

	// 分类：国际前缀后包含非数字或分隔符（国际号码应仅为 +digits 或 00digits）
	std::vector<std::string> invalidPhones_intlSeparators = {
			"+44-7911123456", // 含 '-'（你的规则视为非法）
			"+86 13812345678",// 含空格
			"+1 (234)5678901",// 括号与空格
			"+49.1512345678", // 点号
			"+44+7911123456", // 多余 +
			"+-441234567890", // 非法符号顺序
			"+44(791)1123456",// 不允许括号
			"+44  7911123456" // 多空格
	};

	// 分类："00" 前缀但包含分隔或非数字
	std::vector<std::string> invalidPhones_00Separators = {
			"00-44123456789",
			"00 44123456789",
			"00(44)123456789",
			"0044-79-11123456"};

	// 分类：包含字母或混合字母数字
	std::vector<std::string> invalidPhones_letters = {
			"13812A45678",  // 包含字母
			"+44abcd123456",// 字母混入
			"phone1234567", // 前缀字母
			"12345nine"     // 英文字母单词
	};

	// 分类：含逗号、中文标点、特殊符号
	std::vector<std::string> invalidPhones_specialChars = {
			"138,1234,5678",
			"138。1234。5678",
			"138/1234/5678",
			"138#1234#5678",
			"138*1234*5678"};

	// 分类：连字符滥用或位置错误（例如以连字符开始/结束，多连字符）
	std::vector<std::string> invalidPhones_hyphenMisuse = {
			"-13812345678", // 前导 -
			"13812345678-", // 末尾 -
			"138--12345678",// 连续 --
			"13-812-345678",// 不合理分段
			"010--12345678"};

	// 分类：括号不匹配或错误使用
	std::vector<std::string> invalidPhones_parentheses = {
			"(010-12345678",  // 缺右括号
			"010)-12345678",  // 错误位置右括号
			"+44)7911123456(",// 括号顺序错乱
			"(+8613812345678)"// 整体括在括号里（视规则非法）
	};

	// 分类：带扩展但格式不合法（扩展位置错误）
	std::vector<std::string> invalidPhones_extension = {
			"13812345678ext123",// 非标准扩展写法
			"13812345678 x123", // 空格 x 扩展（非法）
			"+8613812345678#123"// 使用 # 扩展
	};

	// 分类：全角数字或混合全角半角
	std::vector<std::string> invalidPhones_fullwidth = {
			"＋８６１３８１２３４５６７８",// 全角 + 与全角数字
			"１３８１２３４５６７８"       // 全角数字

	};

	// 分类：只含符号或无效前缀
	std::vector<std::string> invalidPhones_symbolsOnly = {
			"++++++",// 仅 +
			"----",  // 仅 -
			"+",     // 仅 +
			"00+"    // 混合无效
	};

	// 将所有非法集合合并（为了遍历方便）
	std::vector<std::string> allInvalid;
	allInvalid.insert(allInvalid.end(), invalidPhones_empty.begin(), invalidPhones_empty.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_tooShort.begin(), invalidPhones_tooShort.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_tooLong.begin(), invalidPhones_tooLong.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_intlSeparators.begin(), invalidPhones_intlSeparators.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_00Separators.begin(), invalidPhones_00Separators.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_letters.begin(), invalidPhones_letters.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_specialChars.begin(), invalidPhones_specialChars.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_hyphenMisuse.begin(), invalidPhones_hyphenMisuse.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_parentheses.begin(), invalidPhones_parentheses.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_extension.begin(), invalidPhones_extension.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_fullwidth.begin(), invalidPhones_fullwidth.end());
	allInvalid.insert(allInvalid.end(), invalidPhones_symbolsOnly.begin(), invalidPhones_symbolsOnly.end());

	// 输出测试（LOG_INFO 宏假定存在，循环变量名 phoneX 保证唯一）
	for (const auto& phoneX: allInvalid)
	{
		LOG_INFO("❌ Invalid Phone test: " + phoneX + " -> ", StringVerify::isPhoneNumber(phoneX));
	}

	LOG_INFO("======================= 日期时间测试=======================");
	// ✅ 合法日期时间
	std::vector<std::string> validDates = {
			"2025-09-11 14:30:00",
			"2025/09/11",
			"2024-02-29 00:00:00",
			"1999-12-31",
			"2000-02-29"};
	for (const auto& d: validDates)
		LOG_INFO("✅ DateTime test: " + d + " -> ", StringVerify::isDateTime(d));

	// ❌ 非法日期时间
	std::vector<std::string> invalidDates = {
			"2025-02-29",// 非闰年
			"invalid-date",
			"",
			"2025-13-01",// 月份错误
			"2025-00-10"};
	for (const auto& d: invalidDates)
		LOG_INFO("❌ DateTime test: " + d + " -> ", StringVerify::isDateTime(d));

	LOG_INFO("======================= URL测试 =======================");
	// ✅ 合法 URL
	std::vector<std::string> validUrls = {
			"http://example.com",
			"https://www.baidu.com",
			"https://a-b.test.com/path?q=123&lang=cn",
			"http://sub.domain.co.uk/",
			"https://UPPERCASE-DOMAIN.COM",
			"https://127.0.0.1/test",
			"http://localhost/",
			"https://example.com:8080/path",
			"https://example.com/index.html?param=value#section",
			"https://i-blog.csdnimg.cn/blog_migrate/258099b2c8b250572d7d9599aebb4398.png#pic_center"};
	for (const auto& u: validUrls)
		LOG_INFO("✅ URL test: " + u + " -> ", StringVerify::isUrl(u));

	// ❌ 非法 URL
	std::vector<std::string> invalidUrls = {
			"ftp://example.com",
			"://missing.scheme.com",
			"http//missing-colon.com",
			"https://",
			"just-a-string",
			"www.no-scheme.com",
			"http:/one-slash.com",
			"https://bad_domain,com",
			"http://incomplete..com"};
	for (const auto& u: invalidUrls)
		LOG_INFO("❌ URL test: " + u + " -> ", StringVerify::isUrl(u));

	LOG_INFO("======================= 字母数字测试 =======================");
	// ✅ 合法字母数字
	std::vector<std::string> validAlnums = {
			"Test123",
			"abcDEF",
			"123456",
			"MixedCASE123",
			"",
			"ALLUPPER",
			"alllower"};
	for (const auto& s: validAlnums)
		LOG_INFO("✅ Alphanumeric test: " + s + " -> ", StringVerify::isAlphanumeric(s));

	// ❌ 非法字母数字
	std::vector<std::string> invalidAlnums = {
			"invalid_string!",
			"with space",
			"special@#"};
	for (const auto& s: invalidAlnums)
		LOG_INFO("❌ Alphanumeric test: " + s + " -> ", StringVerify::isAlphanumeric(s));
}

void StringVerifyTest::cleanupTestCase()
{
}

int main(int argc, char** argv)
{

	// 设置Windows控制台编码
#ifdef Q_OS_WIN
	// 设置控制台输出代码页为 UTF-8
	SetConsoleOutputCP(CP_UTF8);
	// 可选：设置控制台输入为 UTF-8
	SetConsoleCP(CP_UTF8);
#endif
	QApplication app(argc, argv);
	StringVerifyTest tc;
	return QTest::qExec(&tc, argc, argv);// qExec 会把失败信息打印到 stdout
}